package top.ranzhang.service.impl;

import ch.qos.logback.core.joran.util.beans.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import top.ranzhang.bean.dto.AddChildDTO;
import top.ranzhang.bean.dto.ChildToUserDTO;
import top.ranzhang.bean.dto.PageChildDTO;
import top.ranzhang.bean.entity.Child;
import top.ranzhang.bean.entity.User;
import top.ranzhang.bean.vo.ChildNameIdVO;
import top.ranzhang.bean.vo.ChildSexCount;
import top.ranzhang.bean.vo.ChildSexCountVO;
import top.ranzhang.bean.vo.PageChildVO;
import top.ranzhang.common.result.PageResult;
import top.ranzhang.constant.SearchBirthdayDay;
import top.ranzhang.constant.SexConstant;
import top.ranzhang.mapper.ChildMapper;
import top.ranzhang.mapper.UserMapper;
import top.ranzhang.service.IChildService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ran
 * @since 2025-04-14
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChildServiceImpl extends ServiceImpl<ChildMapper, Child> implements IChildService {

    private final UserMapper userMapper;
    private final ChildMapper childMapper;

    /**
     * 添加用户
     * @param addChildDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(AddChildDTO addChildDTO) {
        Child child = new Child();
        // 拷贝对象
        BeanUtils.copyProperties(addChildDTO,child);
        // 创建现在时间为创建时间
        child.setCreateTime(LocalDateTime.now());
        User user = addChildDTO.getUser();
        //等同Admin的登录
        User one = Db.lambdaQuery(User.class)
                .eq(User::getUsername, user.getUsername())
                .one();
        if(one == null){
            userMapper.insert(user);
            child.setUserId(user.getId());
        }else{
            child.setUserId(one.getId());
        }
        //mybatis-plus的Db类包含了很多数据库对应的curd，可以直接调用，不要写mapper
        Db.save(child);
    }

    /**
     * 分页查询
     * @param pageChildDTO
     * @return
     */


    @Override
    public PageResult PageList(PageChildDTO pageChildDTO) {
        // 分页查询
        //（第几页，一页多少条）
        IPage<PageChildDTO> page = new Page<>(pageChildDTO.getPage(),pageChildDTO.getPageSize());
//        LambdaQueryWrapper<PageChildDTO> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper
//                .like(name != null && name != "",PageChildDTO::getName,name)
//                .like(parentalName != null && parentalName != "",PageChildDTO::getParentalName,parentalName)
//                .eq(sex != null,PageChildDTO::getSex,sex);
        IPage<PageChildVO> ChildPage = childMapper.ToPage(page,pageChildDTO);
        ChildPage.getRecords().forEach(item -> {
            item.setAllHour(item.getBuyHour() + item.getGiveHour());
            item.setResidueHour(item.getAllHour() - item.getUseHour());
        });
        return new PageResult(ChildPage.getTotal(),ChildPage.getRecords());
    }

    /**
     * 更新
     * @param childToUserDTO
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void ToUpdateById(ChildToUserDTO childToUserDTO) {
        Child child = new Child();
        User user = childToUserDTO.getUser();
        BeanUtils.copyProperties(childToUserDTO,child);
        user.setId(child.getUserId());
        userMapper.updateById(user);
        childMapper.updateById(child);
    }

    /**
     * 根据id查询
     * @param id
     */
    @Override
    public ChildToUserDTO ToGetById(Integer id) {
        Child one = childMapper.selectById(id);
        User user = userMapper.selectById(one.getUserId());
        ChildToUserDTO childToUserDTO = new ChildToUserDTO();
        BeanUtils.copyProperties(one,childToUserDTO);
        childToUserDTO.setUser(user);
        return childToUserDTO;
    }

    /**
     * 根据id批量删除
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void ToRemoveByIds(List<Integer> ids) {
        // 防止一个家长多个儿童这边用set集合
        HashSet<Integer> userIds = new HashSet<>();
        ids.forEach(id->{
            // 获取用户id
            userIds.add(childMapper.selectById(id).getUserId());
        });
        // 删除儿童
        childMapper.deleteByIds(ids);
        // 判断家长还有没有儿童，如果有不处理，没有删除家长
        userIds.forEach(id->{
            //.list()放回一个列表
            List<Child> list = Db.lambdaQuery(Child.class).eq(Child::getUserId, id).list();
            if(list.size() == 0){
                // 删除家长
                userMapper.deleteById(id);
            }
        });
    }

    /**
     * 获取所有名字
     * @return
     */
    @Override
    public List<ChildNameIdVO> getAllName() {
        List<Child> list = Db.lambdaQuery(Child.class)
                .select(Child::getId, Child::getName)
                .list();
        List<ChildNameIdVO> childNameIdVOS = new ArrayList<>();
        for(Child child: list){
            ChildNameIdVO childNameIdVO = new ChildNameIdVO();
            BeanUtils.copyProperties(child,childNameIdVO);
            childNameIdVOS.add(childNameIdVO);
        }
        return childNameIdVOS;
    }

    /**
     * 统计性别
     * @return
     */
    @Override
    public ChildSexCountVO getChildSexCount() {
        Long allCount = Db.lambdaQuery(Child.class).count();
        Long maleCount = Db.lambdaQuery(Child.class).groupBy(Child::getSex).eq(Child::getSex, 1).count();
        Long femaleCount = Db.lambdaQuery(Child.class).groupBy(Child::getSex).eq(Child::getSex, 0).count();
        List<ChildSexCount> list = List.of(
                new ChildSexCount(maleCount,SexConstant.MALE),
                new ChildSexCount(femaleCount,SexConstant.FEMALE)
        );
        return ChildSexCountVO.builder()
                .allCount(allCount)
                .childSexCountList(list)
                .build();
    }

    /**
     * 根据生日最近几天的数据
     * @param pageChildDTO
     * @return
     */
    @Override
    public PageResult getBirthdayRange(PageChildDTO pageChildDTO) {
        // 获取当前时间
        LocalDate now = LocalDate.now();
        LocalDate start = LocalDate.now();
        String year = String.valueOf(start.getYear());
        // 获取当前时间加7天
        LocalDate end = now.plusDays(SearchBirthdayDay.BirthdayDayLen);
        // 分页查询
        IPage<PageChildVO> page = new Page<>(pageChildDTO.getPage(),pageChildDTO.getPageSize());
        IPage<PageChildVO> pageBirthdayRange = childMapper.getBirthdayRange(page, pageChildDTO, start,end,year);
        return new PageResult(pageBirthdayRange.getTotal(),pageBirthdayRange.getRecords());
    }
}
